<?PHP
/**
 *	微信公众平台PHP-SDK
 *  @author dodgepudding@gmail.com
 *  @link https://github.com/dodgepudding/wechat-php-sdk
 *  @version 1.2
 *  usage:
 *   $options = array(
 *			'token'=>'tokenaccesskey', //填写您设定的key
 *			'appid'=>'wxdk1234567890', //填写高级调用功能的app id
 *			'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
 *		);
 *	 $weObj = new Wechat($options);
 *   $weObj->valid();
 *   $type = $weObj->getRev()->getRevType();
 *   switch($type) {
 *   		case Wechat::MSGTYPE_TEXT:
 *   			$weObj->text("hello, I'm wechat")->reply();
 *   			exit;
 *   			break;
 *   		case Wechat::MSGTYPE_EVENT:
 *   			....
 *   			break;
 *   		case Wechat::MSGTYPE_IMAGE:
 *   			...
 *   			break;
 *   		default:
 *   			$weObj->text("help info")->reply();
 *   }
 *   
 *   //获取菜单操作:
 *   $menu = $weObj->getMenu();
 *   //设置菜单
 *   $newmenu =  array(
 *   		"button"=>
 *   			array(
 *   				array('type'=>'click','name'=>'最新消息','key'=>'MENU_KEY_NEWS'),
 *   				array('type'=>'view','name'=>'我要搜索','url'=>'http://www.baidu.com'),
 *   				)
  *  		);
 *   $result = $weObj->createMenu($newmenu);
 */
namespace SDF\Lib;

class Wechat {
	const MSGTYPE_TEXT = 'text';
	const MSGTYPE_IMAGE = 'image';
	const MSGTYPE_LOCATION = 'location';
	const MSGTYPE_LINK = 'link';
	const MSGTYPE_EVENT = 'event';
	const MSGTYPE_MUSIC = 'music';
	const MSGTYPE_NEWS = 'news';
	const MSGTYPE_CUSTOMER = 'transfer_customer_service';
	const MSGTYPE_VOICE = 'voice';
	const MSGTYPE_VIDEO = 'video';
	const GROUP_MSGTYPE_NEWS = 'mpnews';
	const API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';
	const AUTH_URL = '/token?grant_type=client_credential&';
	const MENU_CREATE_URL = '/menu/create?';
	const MENU_GET_URL = '/menu/get?';
	const MENU_DELETE_URL = '/menu/delete?';
	const MEDIA_GET_URL = '/media/get?';
	const MEDIA_UPLOAD_URL = '/media/upload?';//新建，上传媒体文件
	const MEDIA_UPLOADNEWS_URL = '/media/uploadnews?';//新建，上传图文消息素材
	const MESSAGE_CUSTOM_SEND_URL='/message/custom/send?';//新建，客服消息接口
	const MESSAGE_MASS_DELETE_URL='/message/mass/delete?';//新建，删除群发
	const MESSAGE_MASS_SEND_URL = '/message/mass/send?';//新建，高级群发接口，根据OpenID列表群发
	const MESSAGE_MASS_SENDALL_URL='/message/mass/sendall?';//新建，根据分组进行群发
	const QRCODE_CREATE_URL='/qrcode/create?';
	const QR_SCENE = 0;
	const QR_LIMIT_SCENE = 1;
	const QRCODE_IMG_URL='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=';
	const USER_GET_URL='/user/get?';
	const USER_INFO_URL='/user/info?';
	const GROUP_GET_URL='/groups/get?';
	const GROUP_GETID_URL='/groups/getid?';//新建，根据openid获取用户所在分组
	const GROUP_CREATE_URL='/groups/create?';
	const GROUP_UPDATE_URL='/groups/update?';
	const GROUP_MEMBER_UPDATE_URL='/groups/members/update?';
	const OAUTH_PREFIX = 'https://open.weixin.qq.com/connect/oauth2';
	const OAUTH_AUTHORIZE_URL = '/authorize?';
	const OAUTH_TOKEN_PREFIX = 'https://api.weixin.qq.com/sns/oauth2';
	const OAUTH_TOKEN_URL = '/access_token?';
	const OAUTH_REFRESH_URL = '/refresh_token?';
	const OAUTH_USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo?';
	
	private $token;
	private $appid;
	private $appsecret;
	private $access_token;
	private $_msg;
	private $_funcflag = false;
	private $_receive;
	public $debug =  false;
	public $errCode = 40001;
	public $errMsg = "no access";
	private $_logcallback;
	
	public function __construct()	{
        $options = array(
            //参数获取地址：https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=1633309932&lang=zh_CN
            'token'=> \WxConf::TOKEN, //令牌(Token)
            'appid'=> \WxConf::APPID, //开发者ID(AppID)
            'appsecret'=> \WxConf::APPSECRET //开发者密码(AppSecret)
        );
		$this->token = isset($options['token'])?$options['token']:'';
		$this->appid = isset($options['appid'])?$options['appid']:'';
		$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';
		$this->debug = isset($options['debug'])?$options['debug']:$this->debug;
		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
	}
	
	/**
	 * For weixin server validation 
	 */	
	private function checkSignature()
	{
        $signature = isset($_GET["signature"])?$_GET["signature"]:'';
        $timestamp = isset($_GET["timestamp"])?$_GET["timestamp"]:'';
        $nonce = isset($_GET["nonce"])?$_GET["nonce"]:'';
        		
		$token = $this->token;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr, SORT_STRING);
		$tmpStr = implode( $tmpArr );
		$tmpStr = sha1( $tmpStr );
		
		if( $tmpStr == $signature ){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * For weixin server validation  校验是否是微信服务器请求
	 * @param bool $return 是否返回
	 */
	public function valid($return=false){
        $echoStr = isset($_GET["echostr"]) ? $_GET["echostr"]: '';
        if ($return) {
        		if ($echoStr) {
        			if ($this->checkSignature()) 
        				return $echoStr;
        			else
        				return false;
        		} else 
        			return $this->checkSignature();
        } else {
	        	if ($echoStr) {
	        		if ($this->checkSignature()){
						die($echoStr);
					}else{
						$this->log('微信服务器校验失败');
						die('no access');
					}
	        	}  else {
					if ($this->checkSignature()) {
						return true;
					}else{
						$this->log('微信服务器校验失败');
						die('no access');
					}
				}
        }
        return false;
    }
    
	/**
	 * 设置发送消息
	 * @param array $msg 消息数组
	 * @param bool $append 是否在原消息数组追加
	 */
    public function Message($msg = '',$append = false){
    		if (is_null($msg)) {
    			$this->_msg =array();
    		}elseif (is_array($msg)) {
    			if ($append)
    				$this->_msg = array_merge($this->_msg,$msg);
    			else
    				$this->_msg = $msg;
    			return $this->_msg;
    		} else {
    			return $this->_msg;
    		}
    }
    
    public function setFuncFlag($flag) {
    		$this->_funcflag = $flag;
    		return $this;
    }
    
    private function log($log){
    		if ($this->debug) {
    			try{
					log::write('debug','微信接口调试',-54654,$log);
				}catch(\Exception $e){
					log::write('error','保存日志时出错');
				}
    		}
    		return false;
    }
    
    /**
     * 获取微信服务器发来的信息
     */
	public function getRev(){
		$postStr = file_get_contents("php://input");
		$this->log($postStr);
		if (!empty($postStr)) {
			$this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
		}
		return $this;
	}
	
	/**
	 * 获取微信服务器发来的信息
	 */
	public function getRevData()
	{
		return $this->_receive;
	}
	
	/**
	 * 获取消息发送者
	 */
	public function getRevFrom() {
		if (isset($this->_receive))
			return $this->_receive['FromUserName'];
		else 
			return false;
	}
	
	/**
	 * 获取消息接受者
	 */
	public function getRevTo() {
		if (isset($this->_receive))
			return $this->_receive['ToUserName'];
		else 
			return false;
	}
	
	/**
	 * 获取接收消息的类型
	 */
	public function getRevType() {
		if (isset($this->_receive['MsgType']))
			return $this->_receive['MsgType'];
		else 
			return false;
	}
	
	/**
	 * 获取消息ID
	 */
	public function getRevID() {
		if (isset($this->_receive['MsgId']))
			return $this->_receive['MsgId'];
		else 
			return false;
	}
	
	/**
	 * 获取消息发送时间
	 */
	public function getRevCtime() {
		if (isset($this->_receive['CreateTime']))
			return $this->_receive['CreateTime'];
		else 
			return false;
	}
	
	/**
	 * 获取接收消息内容正文
	 */
	public function getRevContent(){
		if (isset($this->_receive['Content']))
			return $this->_receive['Content'];
		else if (isset($this->_receive['Recognition'])) //获取语音识别文字内容，需申请开通
			return $this->_receive['Recognition'];
		else
			return false;
	}
	
	/**
	 * 获取接收消息图片
	 */
	public function getRevPic(){
		if (isset($this->_receive['PicUrl']))
			return $this->_receive['PicUrl'];
		else 
			return false;
	}
	
	/**
	 * 获取接收消息链接
	 */
	public function getRevLink(){
		if (isset($this->_receive['Url'])){
			return array(
				'url'=>$this->_receive['Url'],
				'title'=>$this->_receive['Title'],
				'description'=>$this->_receive['Description']
			);
		} else 
			return false;
	}
	
	/**
	 * 获取接收地理位置
	 */
	public function getRevGeo(){
		if (isset($this->_receive['Location_X'])){
			return array(
				'lat'=>$this->_receive['Location_X'],
				'lng'=>$this->_receive['Location_Y'],
				'scale'=>$this->_receive['Scale'],
				'label'=>$this->_receive['Label'],
				'precision'=>''
			);
		} else 
			return false;
	}
	
	/**
	 * 获取接收事件推送地理位置
	 *  <Latitude>23.137466</Latitude>
		<Longitude>113.352425</Longitude>
		<Precision>119.385040</Precision>
	 */
     public function getRevEventGeo(){
		if (isset($this->_receive['Longitude'])){
			return array(
					'lat'=>$this->_receive['Latitude'],
					'lng'=>$this->_receive['Longitude'],
					'scale'=>'',
					'label'=>'',
					'precision'=>$this->_receive['Precision']
			);
		} else
			return false;
	}
	
	/**
	 * 获取接收事件推送
	 */
	public function getRevEvent(){
		if (isset($this->_receive['Event'])){
			return array(
				'event'=>@$this->_receive['Event'],
				'key'=>@$this->_receive['EventKey'],
			);
		} else 
			return false;
	}
	
	/**
	 * 获取接收语言推送
	 */
	public function getRevVoice(){
		if (isset($this->_receive['MediaId'])){
			return array(
				'mediaid'=>$this->_receive['MediaId'],
				'format'=>$this->_receive['Format'],
			);
		} else 
			return false;
	}	
	
	/**
	 * 获取接收视频推送
	 */
	public function getRevVideo(){
		if (isset($this->_receive['MediaId'])){
			return array(
					'mediaid'=>$this->_receive['MediaId'],
					'thumbmediaid'=>$this->_receive['ThumbMediaId']
			);
		} else
			return false;
	}
	
	public static function xmlSafeStr($str)
	{   
		return '<![CDATA['.preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/",'',$str).']]>';   
	} 
	
	/**
	 * 数据XML编码
	 * @param mixed $data 数据
	 * @return string
	 */
	public static function data_to_xml($data) {
	    $xml = '';
	    foreach ($data as $key => $val) {
	        is_numeric($key) && $key = "item id=\"$key\"";
	        $xml    .=  "<$key>";
	        $xml    .=  ( is_array($val) || is_object($val)) ? self::data_to_xml($val)  : self::xmlSafeStr($val);
	        list($key, ) = explode(' ', $key);
	        $xml    .=  "</$key>";
	    }
	    return $xml;
	}	
	
	/**
	 * XML编码
	 * @param mixed $data 数据
	 * @param string $root 根节点名
	 * @param string $item 数字索引的子节点名
	 * @param string $attr 根节点属性
	 * @param string $id   数字索引子节点key转换的属性名
	 * @param string $encoding 数据编码
	 * @return string
	*/
	public function xml_encode($data, $root='xml', $item='item', $attr='', $id='id', $encoding='utf-8') {
	    if(is_array($attr)){
	        $_attr = array();
	        foreach ($attr as $key => $value) {
	            $_attr[] = "{$key}=\"{$value}\"";
	        }
	        $attr = implode(' ', $_attr);
	    }
	    $attr   = trim($attr);
	    $attr   = empty($attr) ? '' : " {$attr}";
	    $xml   = "<{$root}{$attr}>";
	    $xml   .= self::data_to_xml($data, $item, $id);
	    $xml   .= "</{$root}>";
	    return $xml;
	}
	
	/**
	 * 设置回复消息
	 * Examle: $obj->text('hello')->reply();
	 * @param string $text
	 */
	public function text($text='')
	{
		$FuncFlag = $this->_funcflag ? 1 : 0;
		$msg = array(
			'ToUserName' => $this->getRevFrom(),
			'FromUserName'=>$this->getRevTo(),
			'MsgType'=>self::MSGTYPE_TEXT,
			'Content'=>$text,
			'CreateTime'=>time(),
			'FuncFlag'=>$FuncFlag
		);
		$this->Message($msg);
		return $this;
	}

	/**
	 *
	 * 设置回复图片消息
	 * Examle: $obj->image('hello')->reply();
	 * @param string $MediaId	通过素材管理接口上传多媒体文件，得到的id
	 * @return $this
	 */
	public function image($MediaId=''){
		$FuncFlag = $this->_funcflag ? 1 : 0;
		$msg = array(
			'ToUserName' => $this->getRevFrom(),
			'FromUserName'=>$this->getRevTo(),
			'MsgType'=>self::MSGTYPE_IMAGE,
			'Image'=>array('MediaId'=>$MediaId),
			'CreateTime'=>time(),
			'FuncFlag'=>$FuncFlag
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * 设置回复音乐
	 * @param string $title
	 * @param string $desc
	 * @param string $musicurl
	 * @param string $hgmusicurl
	 
	public function music($title,$desc,$musicurl,$hgmusicurl='') {
		$FuncFlag = $this->_funcflag ? 1 : 0;
		$msg = array(
			'ToUserName' => $this->getRevFrom(),
			'FromUserName'=>$this->getRevTo(),
			'CreateTime'=>time(),
			'MsgType'=>self::MSGTYPE_MUSIC,
			'Music'=>array(
				'Title'=>$title,
				'Description'=>$desc,
				'MusicUrl'=>$musicurl,
				'HQMusicUrl'=>$hgmusicurl
			),
			'FuncFlag'=>$FuncFlag
		);
		$this->Message($msg);
		return $this;
	}*/
	
	/**
	 * 设置回复图文
	 * @param array $newsData 
	 * 数组结构:
	 *  array(
	 *  	[0]=>array(
	 *  		'Title'=>'msg title',
	 *  		'Description'=>'summary text',
	 *  		'PicUrl'=>'http://www.domain.com/1.jpg',
	 *  		'Url'=>'http://www.domain.com/1.html'
	 *  	),
	 *  	[1]=>....
	 *  )
	 */
	public function news($newsData=array())
	{
		$FuncFlag = $this->_funcflag ? 1 : 0;
		$count = count($newsData);
		
		$msg = array(
			'ToUserName' => $this->getRevFrom(),
			'FromUserName'=>$this->getRevTo(),
			'MsgType'=>self::MSGTYPE_NEWS,
			'CreateTime'=>time(),
			'ArticleCount'=>$count,
			'Articles'=>$newsData,
			'FuncFlag'=>$FuncFlag
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * 设置将消息转发到多客服
	 *
	 *  <xml>
		<ToUserName><![CDATA[touser]]></ToUserName> 开发者微信号 
		<FromUserName><![CDATA[fromuser]]></FromUserName> 发送方帐号（一个OpenID） 
		<CreateTime>1399197672</CreateTime>
		<MsgType><![CDATA[transfer_customer_service]]></MsgType>  transfer_customer_service，表明这是一条多客服消息 
		</xml>
	 */
	public function transferCustomers()
	{
		$FuncFlag = $this->_funcflag ? 1 : 0;
		
		$msg = array(
				'ToUserName' =>$this->getRevFrom(),
				'FromUserName'=>$this->getRevTo(),
				'MsgType'=>self::MSGTYPE_CUSTOMER,
				'CreateTime'=>time(),
				'FuncFlag'=>$FuncFlag
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * 回复微信服务器, 此函数支持链式操作
	 * Example: $this->text('msg tips')->reply();
	 * @param string $msg 要发送的信息, 默认取$this->_msg
	 * @param bool $return 是否返回信息而不抛出到浏览器 默认:否
	 */
	public function reply($msg=array(),$return = false)	{
		if (empty($msg)) $msg = $this->_msg;
		$xmldata =  $this->xml_encode($msg);
		/*log::write('debug','xmldata',0,$xmldata);
		log::write('debug','msg',0,$msg);*/
		$this->log($xmldata);
		if ($return)
			return $xmldata;
		else
			echo $xmldata;
	}
	
	/**
	 * GET 请求
	 * @param string $url
	*/
	private function http_get($url){
		$oCurl = curl_init();
		if(stripos($url,"https://")!==FALSE){
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
		}
		curl_setopt($oCurl, CURLOPT_URL, $url);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
		$sContent = curl_exec($oCurl);
		$aStatus = curl_getinfo($oCurl);
		curl_close($oCurl);
		if(intval($aStatus["http_code"])==200){
			return $sContent;
		}else{
			return false;
		}
	}
		
	/**
	 * POST 请求
	 * @param string $url 
	 * @param array $param 
	 * @return string content
	*/
	private function http_post($url,$param){
		$oCurl = curl_init();
		if(stripos($url,"https://")!==FALSE){
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		}
		if (is_string($param)) {
			$strPOST = $param;
		} else {
			$aPOST = array();
			foreach($param as $key=>$val){
				$aPOST[] = $key."=".urlencode($val);
			}
			$strPOST =  join("&", $aPOST);
		}
		curl_setopt($oCurl, CURLOPT_URL, $url);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
		curl_setopt($oCurl, CURLOPT_POST,true);
		curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
		$sContent = curl_exec($oCurl);
		$aStatus = curl_getinfo($oCurl);
		curl_close($oCurl);
		if(intval($aStatus["http_code"])==200){
			return $sContent;
		}else{
			return false;
		}
	}

	/**
	 * (自定义)POST请求,只在上传媒体文件时使用
	 * @param string $url
	 * @param array $param
	 * @return string content
	 */
	public function http_request($url,$param){
		$oCurl = curl_init();
		if(stripos($url,"https://")!==FALSE){
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
			curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		}
		curl_setopt($oCurl, CURLOPT_URL, $url); //需要获取的url地址
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );//将curl_exec()获取的信息以文件流的形式返回，而不是直接输出
		curl_setopt($oCurl, CURLOPT_POST,true);
		curl_setopt($oCurl, CURLOPT_POSTFIELDS,$param); //允许已数组作为值
		$sContent = curl_exec($oCurl);
		$aStatus = curl_getinfo($oCurl);
		curl_close($oCurl);
		if(intval($aStatus["http_code"])==200){
			return $sContent;
		}else{
			return false;
		}
	}


	/**
	 * 通用auth验证方法，暂时仅用于菜单更新操作
	 * @param string $appid
	 * @param string $appsecret
	 * @return bool|null
	 */
	private function checkAuth($appid='',$appsecret=''){
		if(PHP_OS != 'Linux'){//不是Linux服务器是，不允许重新获取token
			return false;
		}
		if (!$appid || !$appsecret) {
			$appid = $this->appid;
			$appsecret = $this->appsecret;
		}
		$authname = 'wechat_access_token'.$appid;
		$Cache = new \SDF\Common\Cache();
		if ($rs = $Cache->get($authname))  {
			$this->access_token = $rs;
            //todo 需要校验access_token是否已经过期
			return $rs;
		}
		$result = $this->http_get(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$appid.'&secret='.$appsecret);
		//var_dump($result);
		if ($result){
			$json = json_decode($result,true);
			if (!$json || isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				//log::write('error','获取token失败',0,$json);
				return false;
			}
			$this->access_token = $json['access_token'];
            //print_r($json);
			$expire = 3600;
			$Cache->set($authname,$this->access_token,$expire);
			return $this->access_token;
		}
		return false;
	}
	
	/**
	 * 删除验证数据
	 * @param string $appid
	 */
	public function resetAuth($appid=''){
		$this->access_token = '';
		$authname = 'wechat_access_token'.$appid;
		S($authname,null);
		return true;
	}
	
	/**
	 * 微信api不支持中文转义的json结构
	 * @param array $arr
	 */
	static function json_encode($arr) {
		$parts = array ();
		$is_list = false;
		//Find out if the given array is a numerical array
		$keys = array_keys ( $arr );
		$max_length = count ( $arr ) - 1;
		if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1
			$is_list = true;
			for($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position
				if ($i != $keys [$i]) { //A key fails at position check.
					$is_list = false; //It is an associative array.
					break;
				}
			}
		}
		foreach ( $arr as $key => $value ) {
			if (is_array ( $value )) { //Custom handling for arrays
				if ($is_list)
					$parts [] = self::json_encode ( $value ); /* :RECURSION: */
				else
					$parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */
			} else {
				$str = '';
				if (! $is_list)
					$str = '"' . $key . '":';
				//Custom handling for multiple data types
				if (is_numeric ( $value ) && $value<2000000000)
					$str .= $value; //Numbers
				elseif ($value === false)
				$str .= 'false'; //The booleans
				elseif ($value === true)
				$str .= 'true';
				else
					$str .= '"' . addslashes ( $value ) . '"'; //All other things
				// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
				$parts [] = $str;
			}
		}
		$json = implode ( ',', $parts );
		if ($is_list)
			return '[' . $json . ']'; //Return numerical JSON
		return '{' . $json . '}'; //Return associative JSON
	}

	/**
	 * 创建菜单
	 * @param array $data 菜单数组数据
	 * example:
		  {
		     "button":[
		     {	
		          "type":"click",
		          "name":"今日歌曲",
		          "key":"MENU_KEY_MUSIC"
		      },
		      {
		           "type":"view",
		           "name":"歌手简介",
		           "url":"http://www.qq.com/"
		      },
		      {
		           "name":"菜单",
		           "sub_button":[
		            {
		               "type":"click",
		               "name":"hello word",
		               "key":"MENU_KEY_MENU"
		            },
		            {
		               "type":"click",
		               "name":"赞一下我们",
		               "key":"MENU_KEY_GOOD"
		            }]
		       }]
		 }
	 */
	public function createMenu($data){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result = $this->http_post(self::API_URL_PREFIX.self::MENU_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return true;
		}
		return false;
	}
	
	/**
	 * 获取菜单
	 * @return array('menu'=>array(....s))
     */
	public function getMenu(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::MENU_GET_URL.'access_token='.$this->access_token);
		if ($result){
			$json = json_decode($result,true);
			if (!$json || isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}
	
	/**
	 * 删除菜单
	 * @return boolean
     */
	public function deleteMenu(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::MENU_DELETE_URL.'access_token='.$this->access_token);
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return true;
		}
		return false;
	}
	
	/**
	 * 根据媒体文件ID获取媒体文件
	 * @param string $media_id 媒体文件id
	 * @return raw data
     */
	public function getMedia($media_id){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::MEDIA_GET_URL.'access_token='.$this->access_token.'&media_id='.$media_id);
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;
	}
	/**
	 * (自定义)上传媒体文件到微信服务器，并获取media_id
	 * @param $media 上传的媒体文件的绝对path
	 * @param $type 上传的媒体文件类型
	 * @return json字符串（成功时返回带media_id的json，失败时返回带errcode的json）
	 */
	public function uploadMedia($media,$type){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result=$this->http_request(self::API_URL_PREFIX.self::MEDIA_UPLOAD_URL.'access_token='.$this->access_token.'&type='.$type, $media);
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;
	
	}
	

	
	/**
	 * (自定义)上传图文消息素材内容
	 * @param array $newsData
	 * 数组结构:
	 *  array(
	 *	  	[0]=>array(
	 *	 	  		'thumb_media_id'=>'qI6_Ze_6PtV7svjolgs-rN6stStuHIjs9_DidOHaj0Q-mwvBelOXCFZiq2OsIU-p',
	 *	 			'author'=>'xxx',
	 *				'title'=>'Happy Day',
	 *	 			'content_source_url'=>'www.qq.com',
	 *	 	 		'content'=>'content',
	 *	 			'digest'=>'digest',
	 *	 			'show_cover_pic'=>'1'
	 *	 	 	),
	 *	  	[1]=>....
	 *	 )
	 */
	public function newsMaterial($newsData=array()){
		$material=array(
				'articles'=>$newsData,
		);
		$this->Message($material);
		return $this;
	}

	/**
	 * (自定义)上传图文消息素材到微信服务器，并获取media_id
	 * @param  $material 上传的图文消息素材
	 * @return json字符串（成功时返回带media_id的json，失败时返回带errcode的json）
	 */
	public function uploadNews($material=array()){
		if (!$this->access_token && !$this->checkAuth()) return false;
		if(empty($material)){
			$material=$this->_msg;
		}
		$result=$this->http_post(self::API_URL_PREFIX.self::MEDIA_UPLOADNEWS_URL.'access_token='.$this->access_token, self::json_encode($material));
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;	
	}
	
	
	/**
	 * 创建二维码ticket
	 * @param int $scene_id 自定义追踪id
	 * @param int $type 0:临时二维码；1:永久二维码(此时expire参数无效)
	 * @param int $expire 临时二维码有效期，最大为1800秒
	 * @return array('ticket'=>'qrcode字串','expire_seconds'=>1800)
	 */
	public function getQRCode($scene_id,$type=0,$expire=1800){
		if (!$this->access_token && !$this->checkAuth()) return false;
        $action_info = array('scene'=>array('scene_id'=>$scene_id));
        if(!is_numeric($scene_id)){
            $action_info = array('scene'=>array('scene_str'=>$scene_id));
        }
		$data = array(
				'action_name'=>$type?"QR_LIMIT_SCENE":"QR_SCENE",
				'expire_seconds'=>$expire,
				'action_info'=>$action_info,
        );
		$result = $this->http_post(self::API_URL_PREFIX.self::QRCODE_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));
		if ($result)
		{
			$json = json_decode($result,true);
			if (empty($json) or @$json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}
	
	/**
	 * 获取二维码图片
	 * @param string $ticket 传入由getQRCode方法生成的ticket参数
	 * @return string url 返回http地址
	 */
	public function getQRUrl($ticket) {
		return self::QRCODE_IMG_URL.$ticket;
	}

    /**
     * 批量获取关注用户列表
     * @param string $next_openid
     * @return bool|mixed
     */
	public function getUserList($next_openid=''){
		if (!$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::USER_GET_URL.'access_token='.$this->access_token.'&next_openid='.$next_openid);
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;
	}
	
	/**
	 * 获取关注者详细信息
	 * @param string $openid
	 * @return array
	 */
	public function getUserInfo($openid){
		if (!$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::USER_INFO_URL.'access_token='.$this->access_token.'&openid='.$openid);
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;
	}
	
	/**
	 * 获取用户分组列表
	 * @return boolean|array
	 
	public function getGroup(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$result = $this->http_get(self::API_URL_PREFIX.self::GROUP_GET_URL.'access_token='.$this->access_token);
		if ($result)
		{
			$json = json_decode($result,true);
			if (isset($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $result;
		}
		return false;
	}*/
	
	/**
	 * 新增自定分组
	 * @param string $name 分组名称
	 * @return boolean|array
	 
	public function createGroup($name){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$data = array(
				'group'=>array('name'=>$name)
		);
		$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}*/
	
	/**
	 * 更改分组名称
	 * @param int $groupid 分组id
	 * @param string $name 分组名称
	 * @return boolean|array
	 
	public function updateGroup($groupid,$name){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$data = array(
				'group'=>array('id'=>$groupid,'name'=>$name)
		);
		$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}*/
	
	/**
	 * 移动用户分组
	 * @param int $groupid 分组id
	 * @param string $openid 用户openid
	 * @return boolean|array
	 
	public function updateGroupMembers($groupid,$openid){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$data = array(
				'openid'=>$openid,
				'to_groupid'=>$groupid
		);
		$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_MEMBER_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}*/
	
	
	
	/**
	 * (自定义)获取返回json字符串中的errcode
	 *
	 */
	public function getErrCode(){
		if(isset($this->errCode)){
			return $this->errCode;
		}
		return null;
	}
	
	/**
	 * (自定义)获取返回json字符串中的errcode和 errmsg
	 * public function getError(){
	 * 		$error=array();
	 * 		if(isset($this->errCode)&&isset($this->errMsg)){
				$error['errcode']=$this->errCode;
				$error['errmsg']=$this->errmsg;
				return $error;
			}
			return null;
	 * }
	 */

	/**
	 * (自定义)发送文字客服消息
	 * @param $touser 接收对象openid
	 * @param string $content 文本内容
	 */
	public function customText($toUser, $content){
		$msg=array(
				'touser'=>$toUser,
				'msgtype'=>self::MSGTYPE_TEXT,
				'text'=>array(
						'content'=>$content
				)
		);
		$this->Message($msg);
		return $this;
	}

	/**
	 * (自定义)发送图文客服消息
	 * @param $touser 接收对象
	 * @param array $newsData  图文消息的内容主体
	 * 数组结构:
	 *  array(
	 *  	[0]=>array(
	 *  		'title'=>'msg title',
	 *  		'description'=>'summary text',
	 *  		'picUrl'=>'http://www.domain.com/1.jpg',
	 *  		'url'=>'http://www.domain.com/1.html'
	 *  	),
	 *  	[1]=>....
	 *  )
	 */
	public function customNews($toUser,$newsData=array()){
		$msg=array(
				'touser'=>$toUser,
				'msgtype'=>self::MSGTYPE_NEWS,
				'news'=>array(
						'articles'=>$newsData
				)
		);
		$this->Message($msg);
		return $this;
	}

	/**
	 * (自定义)用于主动发送客服消息
	 *
	 */
	public function customSend($msg=array()){
		if (!$this->access_token and !$this->checkAuth()) return false;//验证access_token
		if(empty($msg)){
			$msg=$this->_msg;
		}
        $url = self::API_URL_PREFIX.self::MESSAGE_CUSTOM_SEND_URL.'access_token='.urlencode($this->access_token);
		$result = $this->http_post($url, self::json_encode($msg));//得到微信服务器返回的json字符串
        //print_r($result );
		if($result){
			$json = json_decode($result, true);//解码json为数组
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}

    /**
     * (自定义)用于主动发送客服消息
     *
     */
    public function customSend1($msg=array()){
        if (!$this->checkAuth()) return false;//验证access_token
        if(empty($msg)){
            $msg=$this->_msg;
        }
        $url = self::API_URL_PREFIX.self::MESSAGE_CUSTOM_SEND_URL.'access_token='.urlencode($this->access_token);
        $result = $this->http_post($url, self::json_encode($msg));//得到微信服务器返回的json字符串
        //print_r($result );
        if($result){
            $json = json_decode($result, true);//解码json为数组
            if (!$json || $json['errcode']>0) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

	/**
	 * (自定义)高级群发接口文本消息(根据分组发送)
	 * @param $group_id 群发分组编号
	 * @param $content 文本内容
	 */
	public function groupText($group_id,$content){
		$msg=array(
				'filter'=>array(
						'group_id'=>$group_id
				),
				'text'=>array(
						'content'=>$content
				),
				'msgtype'=>	self::MSGTYPE_TEXT
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * (自定义)高级群发接口图文消息(根据分组发送)
	 * @param $group_id 群发分组编号
	 * @param $media_id 图文素材编号
	 */
	public function groupNews($group_id,$media_id){
		$msg=array(
				'filter'=>array(
							'group_id'=>$group_id
				),
				'mpnews'=>array(
							'media_id'=>$media_id
				),
				'msgtype'=>	self::GROUP_MSGTYPE_NEWS		
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * (自定义)高级群发接口根据分组发送消息
	 * @param array $msg 群发消息主体
	 * @return 包含errcode、errmsg和msg_id的json字符串
	 */
	public function groupSendAll($msg=array()){
		if (!$this->access_token && !$this->checkAuth()) return false;
		if(empty($msg)){
			$msg=$this->_msg;
		}
		$result=$this->http_post(self::API_URL_PREFIX.self::MESSAGE_MASS_SENDALL_URL.'access_token='.$this->access_token,self::json_encode($msg));//得到微信服务器返回的json字符串
		if($result){
			$json = json_decode($result,true);//解码json为数组
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}
	
	/**
	 * (自定义)高级群发接口文本消息(根据openid发送)
	 * @param array $openid 接收的openid数组
	 * @param $content 文本内容
	 */
	public function openidText($openid=array(),$content){
		$msg=array(
				'touser'=>$openid,
				'text'=>array(
						'content'=>$content
				),
				'msgtype'=>	self::MSGTYPE_TEXT
		);
		$this->Message($msg);
		return $this;
	}
	
	/**
	 * (自定义)高级群发接口图文消息(根据openid发送)
	 * @param array $openid 用户的openid数组，最多10000
	 * @param $media_id 图文素材编号
	 */
	public function openidNews($openid=array(),$media_id){
		$msg=array(
				'touser'=>$openid,
				'mpnews'=>array(
						'media_id'=>$media_id
				),
				'msgtype'=>	self::GROUP_MSGTYPE_NEWS
		);
		$this->Message($msg);
		return $this;
	}
	
	
	/**
	 * (自定义)高级群发接口根据openid发送消息，单次最多10000
	 * @param $msg 群发消息主体
	 * @return 包含errcode、errmsg和msg_id的json字符串
	 */
	public function openidSend($msg){
		if (!$this->access_token && !$this->checkAuth()) return false;
		if(empty($msg)){
			$msg=$this->_msg;
		}
		$result=$this->http_post(self::API_URL_PREFIX.self::MESSAGE_MASS_SEND_URL.'access_token='.$this->access_token,self::json_encode($msg));//得到微信服务器返回的json字符串
		if($result){
			$json = json_decode($result,true);//解码json为数组
			if (!$json || $json['errcode']>0) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}
	
	
	
	/**
	 * oauth 授权跳转接口
	 * @param string $callback 回调URI
	 * @return string
	 */
	public function getOauthRedirect($callback,$state='',$scope='snsapi_userinfo'){
		return self::OAUTH_PREFIX.self::OAUTH_AUTHORIZE_URL.'appid='.$this->appid.'&redirect_uri='.urlencode($callback).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';
	}
	
	/**
	 * 通过code获取Access Token
	 * @return array {access_token,expires_in,refresh_token,openid,scope}
	 */
	public function getOauthAccessToken(){
		$code = isset($_GET['code'])?$_GET['code']:'';
		if (!$code) return false;
		$result = $this->http_get(self::OAUTH_TOKEN_PREFIX.self::OAUTH_TOKEN_URL.'appid='.$this->appid.'&secret='.$this->appsecret.'&code='.$code.'&grant_type=authorization_code');
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || !empty($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			$this->user_token = $json['access_token'];
			return $json;
		}
		return false;
	}
	
	/**
	 * 刷新access token并续期
	 * @param string $refresh_token
	 * @return boolean|mixed
	 */
	public function getOauthRefreshToken($refresh_token){
		$result = $this->http_get(self::OAUTH_TOKEN_PREFIX.self::OAUTH_REFRESH_URL.'appid='.$this->appid.'&grant_type=refresh_token&refresh_token='.$refresh_token);
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || !empty($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			$this->user_token = $json['access_token'];
			return $json;
		}
		return false;
	}
	
	/**
	 * 获取授权后的用户资料
	 * @param string $access_token
	 * @param string $openid
	 * @return array {openid,nickname,sex,province,city,country,headimgurl,privilege}
	 */
	public function getOauthUserinfo($access_token,$openid){
		$result = $this->http_get(self::OAUTH_USERINFO_URL.'access_token='.$access_token.'&openid='.$openid);
		if ($result)
		{
			$json = json_decode($result,true);
			if (!$json || !empty($json['errcode'])) {
				$this->errCode = $json['errcode'];
				$this->errMsg = $json['errmsg'];
				return false;
			}
			return $json;
		}
		return false;
	}
	
	
	
	//下述接口为新增支持获取微信Js接口调用的
    /**
     * @param int $length
     * @return string
     */
	private function createNonceStr($length = 16) {
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}

    /**
     *
     * @return string
     */
	private function getJsApiTicket() {
		//从缓存中读取ticket
		$cache_name = 'wechat_jsapi_ticket'.$this->appid;
		$Cache = new \SDF\Common\Cache();
		$ticket = $Cache->get($cache_name);//S($cache_name);
		if ($ticket)  {
			return $ticket;
		}
		//从微信服务器获取ticket
		if (!$this->access_token && !$this->checkAuth()) return '';
		$result = $this->http_get(self::API_URL_PREFIX.'/ticket/getticket?type=jsapi&access_token='.$this->access_token);
		$json = json_decode($result, true);
		$ticket = $json['ticket'];
		if ($ticket) {
			$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;
			$Cache->set($cache_name,$ticket,$expire);
		}
		return $ticket;
	}

    /**
     * 获取js接口的配置验证包
     * @return array
     */
	public function getSignPackage() {
		$jsapiTicket = $this->getJsApiTicket();
		$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
		$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
		$timestamp = time();
		$nonceStr = $this->createNonceStr();
	
		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
		$signature = sha1($string);
		$signPackage = array(
				"appId"     => $this->appid,
				"nonceStr"  => $nonceStr,
				"timestamp" => $timestamp,
				"url"       => $url,
				"signature" => $signature,
				"rawString" => $string
		);
		return $signPackage;
	}

	/**
	 * 获取指定状态的所有商品
	 * @return string
	 */
	public function getGoodsByStatus(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = "https://api.weixin.qq.com/merchant/getbystatus?access_token=".$this->access_token;
		$result = $this->http_post($url,array('status'=>1));//获取上架的商品
		return $result;
	}

	/**
	 * 获取所有分组
	 * @return bool|string
	 */
	public function getGroupAll(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = "https://api.weixin.qq.com/merchant/group/getall?access_token=".$this->access_token;
		$result = $this->http_post($url,array());
		return $result;
	}

	/**
	 * 根据分组ID获取分组信息
	 * @param $id
	 * @return bool|string
	 */
	public function getGroupById($id){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = "https://api.weixin.qq.com/merchant/group/getbyid?access_token=".$this->access_token;
		$result = $this->http_post($url,json_encode(array("group_id"=>$id)));
		return $result;
	}

	/**
	 * 模板消息
	 * @param $templatenews_code
	 * @return bool|string
	 */
	public function get_templatenews_id($templatenews_code){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$param = array(
			'template_id_short'=>$templatenews_code
		);
		$url = 'https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token='.$this->access_token;
		$rs = $this->http_post($url,json_encode($param));
		return $rs;
	}

	/**
	 * 发送模板消息
	 * @param $param
	 * @return bool|string
	 */
	public function send_template_news($param){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$this->access_token;
		$rs = $this->http_post($url,json_encode($param));
		return $rs;
	}

    /**
     * 发送模板消息
     * @param $param
     * @return bool|string
     */
    public function send_template_news1($param){
        if (!$this->checkAuth()) return false;
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$this->access_token;
        $rs = $this->http_post($url,json_encode($param));
        return $rs;
    }

	/**
	 * 获取永久素材的列表
	 * @param string $type			素材的类型，图片（image）、视频（video）、语音 （voice）、图文（news）
	 * @param int $offset			从全部素材的该偏移位置开始返回，0表示从第一个素材 返回
	 * @param int $count			返回素材的数量，取值在1到20之间
	 * @return bool|string
	 */
	public function batchget_material($type='image',$offset=0,$count=20){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$param = array(
			'type'=>$type,
			'offset'=>$offset,
			'count'=>$count,
		);
		$url = 'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token='.$this->access_token;
		$rs = $this->http_post($url,json_encode($param));
		if($rs){
			return json_decode($rs);
		}
		return $rs;
	}

	/**
	 * 永久素材的总数，也会计算公众平台官网素材管理中的素材
	 * @return bool|mixed|string
	 */
	public function get_materialcount(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = 'https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token='.$this->access_token;
		$rs = $this->http_post($url,json_encode(array()));
		if($rs){
			return json_decode($rs);
		}
		return $rs;
	}

	/**
	 * 获取服务器回调服务器ip
	 */
	public function getcallbackip(){
		if (!$this->access_token && !$this->checkAuth()) return false;
		$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token='.$this->access_token;
		$rs = $this->http_post($url,json_encode(array()));
		if($rs){
			return json_decode($rs);
		}
		return $rs;
	}
}